
#ifndef __EVENT_LISTENER_H__
#define __EVENT_LISTENER_H__

#include "EventBase.h"
#include <functional>
#include <unordered_map>

/*
    事件监听器

    通过SetProcess设置事件处理
    通过Connect连接到派发器，进行监听
    通过DisConnect断开连接器，取消监听

    监听器在以下情况下会自动断开连接
        1. 监听器析构时
        2. 派发器析构时
        3. 重新连接新的派发器时
        4. 当监听器内无事件处理函数时
*/

class EventDispatch;

class EventListener : public Obj
{
public:
    typedef std::function<void(EventBase*)> ListenerFunc;


public:
    EventListener();
    ~EventListener();

    // 设置监听函数
    template<typename Func>
    void SetProcess(const std::string& name, Func func)
    {
        this->funcList_[name] = std::bind(&EventListener::ProxyFunc<Func>, this, func, std::placeholders::_1);
    }

    template<typename CFunc, typename Obj>
    void SetProcess(const std::string& name, CFunc func, Obj* obj)
    {
        this->funcList_[name] = std::bind(&EventListener::ProxyFunc<Func>, this, func, obj, std::placeholders::_1);
    }

    // 设置空监听函数来移除监听
    void SetProcess(const std::string& name);

    // 处理监听事件
    void ProcessEvent(const std::string& name, EventBase* event);

    // 监听连接
    void Connect(EventDispatch* dispatch);

    // 取消监听
    void DisConnect();

    // 检查监听器是否有效
    bool IsValid() const;

    // 检查监听器能否处理此事件
    bool CheckEvent(const std::string& name) const;

    // 获取监听的事件列表
    std::vector<std::string> GetEventList() const;

    // 卸载事件监听
    bool RemoveProcess(const std::string& name);

    // 清理监听事件
    void Clear();
    
private:
    /*
        本地调用的中转函数
    */
	template<typename Func> void ProxyFunc(Func func, EventBase* event) { CallProxy(func, event); }
	template<typename CFunc, typename Obj> void ProxyFunc(CFunc func, Obj* obj, EventBase* event) { CallProxy(func, obj, event); }

    /*
        模板调用代理
    */
	template<typename Type> void CallProxy(void(*func)(Type), EventBase* event) { func(dynamic_cast<Type>(event)); }
	template<typename Type> void CallProxy(std::function<void(Type)> func, EventBase* event) { func(dynamic_cast<Type>(event)); }
	template<typename Cls, typename Obj, typename Type> void CallProxy(void(Cls::*func)(Type), Obj* obj, EventBase* event) { func(dynamic_cast<Type>(event)); }

    /*
        常用的特殊调用代理
    */
    void CallProxy(void(*func)(), EventBase* event) { func(); }
    void CallProxy(void(*func)(EventBase* event), EventBase* event) { func(event); }
    void CallProxy(void(*func)(const std::string& eventName), EventBase* event) { func(event->GetName()); }
    
private:
    std::unordered_map<std::string, ListenerFunc> funcList_;    // 事件处理表
    EventDispatch* dispatch_;                                   // 监听的派发器
};

#endif
